package com.cykj.gateway.config;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.reactor.filter.SaReactorFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson.JSON;
import com.cykj.common.dto.ResponseDTO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * [Sa-Token 权限认证] 配置类 
 */
@Configuration
public class SaTokenConfigure {
    /**
     * 注册 [Sa-Token全局过滤器] 
     */
    @Bean
    public SaReactorFilter saReactorFilter() {
        return new SaReactorFilter()

                // 指定 拦截路由 与 放行路由
                .addInclude("/**")
                .addExclude("/swagger-ui.html")
                .addExclude("/user-module/user/login")
                .addExclude("/user-module/user/enroll")
                .addExclude("/admin-modules/admin/login")
                .addExclude("/admin-modules/validate/get")
                .addExclude("/admin-modules/static/**")
                .addExclude("/enterprise-module/hr/login")
                .addExclude("/enterprise-module/hr/register")
                .addExclude("/enterprise-module/hr/validateCodeImage")
                .addExclude("/enterprise-module/hr/emailValidateCode")
                .addExclude("/enterprise-module/static/**")
                .addExclude("/user-module/static/**")

                // 认证函数: 每次请求执行
                .setAuth(obj -> {
                    System.out.println("---------- 进入Sa-Token全局认证 -----------");
                    StpUtil.checkLogin();

                    // 登录认证 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
//                    SaRouter.match("/**", "/user/doLogin", () -> StpUtil.checkLogin());

                    // 更多拦截处理方式，请参考“路由拦截式鉴权”章节 */
                })

                // 异常处理函数：每次认证函数发生异常时执行此函数
                .setError(e -> {
                    System.out.println("---------- 进入Sa-Token异常处理 -----------");
                    e.printStackTrace();
                    String token = StpUtil.getTokenValue();
                    SaResult saResult = new SaResult();
                    saResult.setCode(SaResult.CODE_NOT_LOGIN);
                    if (token == null){
                        saResult.setMsg("请携带token！");
                    }else{
                        saResult.setMsg("会话已过期");
                    }
                    return saResult;
                });
    }
}